package com.gitee.wsl.doc.sample.opml

import com.gitee.wsl.collections.stack.stackOf
import com.gitee.wsl.doc.xml.EventType
import com.gitee.wsl.doc.xml.XmlPullParser
import com.gitee.wsl.ext.set.peek
import com.gitee.wsl.ext.set.push
import com.gitee.wsl.text.format.format


/**
 * [com.gitee.wsl.doc.sample.opml.OpmlSectionHandler] that deals with the `opml` tag
 */
internal class OpmlInitHandler : com.gitee.wsl.doc.sample.opml.OpmlSectionHandler<String> {
    private val stack  = stackOf<String>()

    private var started = false
    private var version: String? = null

    @Throws(_root_ide_package_.com.gitee.wsl.doc.sample.opml.OpmlParseException::class)
    override fun startTag(xpp: XmlPullParser) {
        _root_ide_package_.com.gitee.wsl.doc.sample.opml.ValidityCheck.requirePosition(xpp, EventType.START_TAG)
        when (xpp.name) {
            "opml" -> {
                if (started) {
                    throw _root_ide_package_.com.gitee.wsl.doc.sample.opml.OpmlParseException("an opml document can not have multiple <opml> elements")
                }
                version = xpp.getAttributeValue(null, "version")
                if (version == null) {
                    throw _root_ide_package_.com.gitee.wsl.doc.sample.opml.OpmlParseException("opml element does not have required attribute version")
                }
                started = true
                stack.push(xpp.name)
            }

            else -> {
                // An OPML file may contain elements and attributes not described on this page,
                // only if those elements are defined in a namespace, as specified by the W3C.
                // http://opml.org/spec2.opml#1629042982000
                if (_root_ide_package_.com.gitee.wsl.doc.sample.opml.ValidityCheck.isTextBlank(xpp.namespace)) {
                    throw _root_ide_package_.com.gitee.wsl.doc.sample.opml.OpmlParseException(
                        String.format(
                            "encountered non-namespaced element <%s> instead of <opml>",
                            xpp.name
                        )
                    )
                }
                stack.push(xpp.namespace + ":" + xpp.name)
            }
        }
    }

    @Throws(_root_ide_package_.com.gitee.wsl.doc.sample.opml.OpmlParseException::class)
    override fun text(xpp: XmlPullParser) {
        if (stack.isEmpty()) {
            _root_ide_package_.com.gitee.wsl.doc.sample.opml.ValidityCheck.requireNoText(xpp, "opml", started)
        } else {
            when (stack.peek()) {
                "opml" -> _root_ide_package_.com.gitee.wsl.doc.sample.opml.ValidityCheck.requireNoText(xpp, "opml", started)
                else -> {}
            }
        }
    }

    @Throws(_root_ide_package_.com.gitee.wsl.doc.sample.opml.OpmlParseException::class)
    override fun endTag(xpp: XmlPullParser) {
        when (stack.peek()) {
            "opml" -> started = false
            else -> {}
        }
    }

    override fun get(): String {
        return version!!
    }
}
